﻿module View

open System.Windows
open System.Windows.Controls
open Layout
open Rendering
open PointerEventTargeting
open Dom
open HtmlParser
open RenderingContext
open Boxes


type DocumentViewController(host:Controls.VisualHostControl, container:ScrollViewer) as this =
    let _host = host
    let _scrollViewer = container
    let mutable _doc : Document option = None
    // keep reference to visual tree to be able to dispatch pointer events
    let mutable _layout = None
    let _drawingVisual = System.Windows.Media.DrawingVisual()
    do
        host.AddVisual(_drawingVisual) 
        host.MouseDown |> Observable.add(fun e -> dispatchPointerEvent _layout.Value "click" (e.GetPosition(_host)))
        container.TextInput.Add(fun e ->
            match _doc with
            | Some doc -> doc.dispatchKeyboardEvent "TextInput" (e.Text.[0])           
            | None -> ())

        (* redraw page when resizing *)
        container.SizeChanged |> Observable.add(fun e ->
            if _doc.IsSome then this.renderPage(_doc.Value))
        

    member this.renderPage (doc:Document) = 
        Application.Current.Dispatcher.Invoke((fun () -> do this.renderPage1 doc))

    member this.renderPage1 (doc:Document) = 
        _doc <- Some doc        

        // render document
        let viewportWidth = _scrollViewer.ViewportWidth
        let viewportHeight = _scrollViewer.ViewportHeight
        
        let drawingContext = _drawingVisual.RenderOpen();

        // clear viewport
        let rect = Rect(Point(0.0, 0.0), 
                    Size(
                        (max _host.Width viewportWidth), 
                        (max _host.Height viewportHeight)))
        drawingContext.DrawRectangle(System.Windows.Media.Brushes.Gray, null, rect);
        // render
        let layout = render doc (int(viewportWidth),int(viewportHeight)) (new RenderingContext(drawingContext, new System.Windows.Point(0.0,0.0)))
        drawingContext.Close()
        do _layout <- Some layout

        let (ElementBoxLayout(BoxSize(w,h), _, _)) = layout

        // resize container to allow whole page
        _host.Width <- max (float(layout.size.width)) viewportWidth
        _host.Height <- max (float(layout.size.height)) viewportHeight
        

        

